/*! \file assert.h
 *	\brief <write description for assert.h>
 *
 *	created:	2009/11/23
 *	created:	23:11:2009   13:58
 *	filename: 	o:\gag-engine\libs\core\assert.h
 *	file path:	o:\gag-engine\libs\core
 *	file base:	assert
 *	file ext:	h
 *	author:		Vitalii Trubchaninov
 *				venngraydog@gmail.com
 */

#ifndef _CORE_ASSERT_H_
#define _CORE_ASSERT_H_

#pragma once

#include <assert.h>

#include "debug.h"
#include "exception.h"
#include "Format.h"

namespace tt{
namespace core{
	void unreachable(const char*);
	void not_implemented();
} //namespace core
} //namespace tt

#define TT_TO_STRING_IMPL(x) #x
#define TT_TO_STRING(x) TT_TO_STRING_IMPL(x)

#define TT_ASSERT_R(expression) \
	if(!(expression)) \
	{ \
		TT_DEBUG_BREAK(); \
		ttThrow( str( tt::core::Format( TEXT("ttAssert: file: %1% line: %2% \nExpression: %3%") ) % TEXT(__FILE__) % TT_TO_STRING(__LINE__) % TEXT(#expression) ) ); \
	}

#define TT_ASSERT_R_MSG(expression, format) \
	if(!(expression)) \
	{ \
		TT_DEBUG_BREAK(); \
		ttThrow(format); \
	}

#define TT_NOT_IMPLEMENTED \
	{ \
		tt::core::not_implemented(); \
		__assume(0); \
	}

#define TT_UNREACHABLE(text) \
	{ \
		tt::core::unreachable( text "\n" __FILE__ "(" TT_TO_STRING(__LINE__) ")"); \
		__assume(0); \
	}

#define TT_UNREACHABLE_EX(text) \
	{ \
		tt::core::unreachable( tt::String(text) + "\n" + __FILE__ + "(" + TT_TO_STRING(__LINE__) + ")"); \
		__assume(0); \
	}

//////////////////////////////////////////////////////////////////////////
#ifdef TT_DEBUG
#	define ttAssert(expression) assert(expression)
#	define ttAssertMsg(expression, format) assert(expression)
#else
#	define ttAssert(expression) ((void)0)
#	define ttAssertMsg(expression, format) ((void)0)
#endif

#endif //_CORE_ASSERT_H_